//
//  DRModel.m
//  opengl_practice
//
//  Created by Daruo on 2022/4/5.
//

#import "DRModel.h"
#import <OpenGLES/ES2/glext.h>  //vertex array object glGenVertexArraysOES方法需要
@implementation DRModel {
    char * _name;
    GLuint _vao;
    GLuint _vertexBuffer;
    GLuint _indexBuffer;
    unsigned int _vertexCount;
    unsigned int _indexCount;
    RWTBaseEffect *_shader;
}
-(instancetype)initWithName:(char *)name shader:(RWTBaseEffect*)shader vertices:(RWTVertex*)vertices vertexCount:(unsigned int)vertexCount indices:(GLubyte *)indices indexCount:(unsigned int)indexCount{
    if (self = [super init]) {
        _name = name;
        _vertexCount = vertexCount;
        _indexCount = indexCount;
        _shader = shader;
        //初始化矩阵信息
        _position = GLKVector3Make(0, 0, 0);
        _rotationX = 0;
        _rotationY = 0;
        _rotationZ = 0;
        _scale = 1.0;
       //创建vertex array object
        //创建vertex buffer
        //创建index buffer
        //各种绑定
        //各种设置属性
        glGenVertexArraysOES(1, &_vao);
        //绑定vertex array object
        glBindVertexArrayOES(_vao);
        
        //生成顶点缓冲区
        //1在GPU生成 顶点缓冲区 glGenBuffers(GLsizei:个数。GLuint*  缓冲区地址)
        glGenBuffers(1, &_vertexBuffer);
        //绑定缓冲区glBindBuffer(GLenum 缓冲区类型, GLuint 缓冲区id)
        glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
        //点cpu定义的顶点缓冲区传给gpu glBufferData(GLenum 缓冲区类型, GLsizeiptr 缓冲区大小, const GLvoid * 顶点数据, GLenum 缓冲区数据的作用，这里为绘制)
        //这里的顶点缓冲区长度修改为模型的长度 sizeof(RWTVertex)
        glBufferData(GL_ARRAY_BUFFER, vertexCount *sizeof(RWTVertex), vertices, GL_STATIC_DRAW);
         
        
        //生成索引缓冲区
        glGenBuffers(1, &_indexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
        //这里索引缓冲区长度修改为 indexCount * sizeof(GLubyte)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLubyte), indices, GL_STATIC_DRAW);
        
        
        
        
        //enable vetex attributes
        glEnableVertexAttribArray(RWTVertexAttribPosition);
        glVertexAttribPointer(RWTVertexAttribPosition, 3, GL_FLOAT, false, sizeof(RWTVertex), (const GLvoid *)offsetof(RWTVertex, Position));
        //激活颜色缓冲区
        glEnableVertexAttribArray(RWTVertexAttribColor);
        glVertexAttribPointer(RWTVertexAttribColor, 4, GL_FLOAT, false, sizeof(RWTVertex), (const GLvoid *)offsetof(RWTVertex, Color));
        
        //清除所有的绑定信息
        glBindVertexArrayOES(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        
    }
    
    return self;
    
}

-(GLKMatrix4)modelMatrix {
    GLKMatrix4 modelMatrix = GLKMatrix4Identity;
    modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, self.position.z);
    modelMatrix = GLKMatrix4Rotate(modelMatrix, self.rotationX , 1, 0, 0);
    modelMatrix = GLKMatrix4Rotate(modelMatrix, self.rotationY , 0, 1, 0);
    modelMatrix = GLKMatrix4Rotate(modelMatrix, self.rotationZ , 0, 0, 1);
    modelMatrix = GLKMatrix4Scale(modelMatrix, self.scale, self.scale, self.scale);

    return  modelMatrix;
}

-(void)renderWithParentModelViewMatrix:(GLKMatrix4)parentModelView{

    GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(parentModelView, [self modelMatrix]);
    
    //为render 的 modelviewmatrix赋值
    _shader.modelViewMatrix = modelViewMatrix;
    [_shader prepareToDraw];

    glBindVertexArrayOES(_vao);
    glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_BYTE, 0);
    //解除绑定
    glBindVertexArrayOES(0);
}

-(void)updateWithDelta:(NSTimeInterval)dt {
    float v1 = CACurrentMediaTime() * 2 * M_PI;
    
    float secsPerMove = 2;
    float v2 = v1 / secsPerMove;
    float v3 = sinf(v2);
    NSLog(@"v1:%f v2:%f v3:%f",v1,v2,v3);
    //the sinf function you know it goes between 1 and -1 over a period of 2π by default
    //but if you multiply the result by 2π and divide by something you want
    //you can swich to another period instead so that's  what we're doing to make it go and
    // I should this to every 2 seconds that's what it's making it go every 2 seconds instead of 2π by defaulut
    self.position = GLKVector3Make(sinf(CACurrentMediaTime() * 2 * M_PI / secsPerMove), self.position.y, self.position.z);
}
@end
